using System.Linq.Expressions;
using Admin.Domain.Entities;
using Admin.Domain.Repositories;
using Admin.Infrastructure.Date;
using Microsoft.EntityFrameworkCore;

namespace Admin.Infrastructure.Repositories;

public class EFRepository<T>(AdminDbContext db) : IRepository<T> where T : EntityBase
{
    private readonly AdminDbContext _db = db;
    private readonly DbSet<T> _tb = db.Set<T>();

    public IQueryable<T> Table
     { get => _tb.AsNoTracking(); set => throw new NotImplementedException(); }

    public async Task AddAsync(T entity)
    {
        await _tb.AddAsync(entity);
        await _db.SaveChangesAsync();
    }

    public async Task<T?> GetOneConditionAsync(Expression<Func<T, bool>> condition)
    {
        return await _tb.Where(item => !item.IsDeleted).FirstOrDefaultAsync(condition);
    }

    public async Task<List<T>> GetListConditionAsync(Expression<Func<T, bool>> condition)
    {
        return await _tb.Where(item => !item.IsDeleted).Where(condition).ToListAsync();
    }

    public async Task<T?> GetByIdAsync(Guid id)
    {
        return await _tb.Where(item => !item.IsDeleted).FirstOrDefaultAsync(item => item.Id == id);
    }

    public async Task<IEnumerable<T>> GetPagedAsync(int pageIndex, int pageSize)
    {
        return await _tb.Where(item => !item.IsDeleted).OrderBy(item => item.CreatedAt).Skip(pageIndex * pageSize).Take(pageSize).ToListAsync();
    }

    public async Task UpdateAsync(T entity)
    {
        entity.UpdatedAt = DateTime.UtcNow;
        _tb.Update(entity);
        await _db.SaveChangesAsync();
    }
}